package com.lianjia.analysis.repository;

import com.lianjia.analysis.model.HouseInfo;
import com.lianjia.analysis.model.dto.HotCityDTO;
import com.lianjia.analysis.model.dto.MonthlyPriceTrendDTO;
import org.springframework.data.mongodb.repository.Aggregation;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 房屋信息数据访问接口
 */
@Repository
public interface HouseInfoRepository extends MongoRepository<HouseInfo, String> {

    /**
     * 查询所有不同的城市
     */
    @Query(value = "{}", fields = "{'cityName': 1}")
    List<HouseInfo> findAllCityNames();

    /**
     * 查询所有不同城市名称（仅返回城市名称）
     */
    @Aggregation(pipeline = {
        "{ $group: { _id: '$cityName' } }",
        "{ $match: { _id: { $ne: null } } }",
        "{ $project: { _id: 0, cityName: '$_id' } }"
    })
    List<String> findDistinctCities();

    /**
     * 计算平均单价
     */
    @Query(value = "{}", fields = "{'price.unitPrice': 1}")
    Double findAverageUnitPrice();

    /**
     * 查询最高单价
     */
    @Query(value = "{}", sort = "{'price.unitPrice': -1}", fields = "{'price.unitPrice': 1}")
    Double findMaxUnitPrice();

    /**
     * 查询最低单价
     */
    @Query(value = "{}", sort = "{'price.unitPrice': 1}", fields = "{'price.unitPrice': 1}")
    Double findMinUnitPrice();

    /**
     * 查询热门城市（房源数量最多的城市）
     */
    @Aggregation(pipeline = {
        "{ $group: { _id: '$cityName', count: { $sum: 1 }, avgPrice: { $avg: '$price.unitPrice' } } }",
        "{ $sort: { count: -1 } }",
        "{ $limit: 10 }",
        "{ $project: { _id: 0, city: '$_id', houseCount: '$count', averagePrice: '$avgPrice' } }"
    })
    List<HotCityDTO> findHotCities();

    /**
     * 根据城市名称查询房屋信息
     */
    List<HouseInfo> findByCityName(String cityName);

    /**
     * 根据城市名称查询房屋信息
     */
    @Query("{'cityName': ?0}")
    List<HouseInfo> findByCity(String city);

    /**
     * 根据城市名称和区域查询房屋信息
     */
    @Query("{'cityName': ?0, 'district': ?1}")
    List<HouseInfo> findByCityAndDistrict(String city, String district);

    /**
     * 根据城市名称和小区查询房屋信息
     */
    @Query("{'cityName': ?0, 'location': {$regex: ?1, $options: 'i'}}")
    List<HouseInfo> findByCityAndCommunity(String city, String community);

    /**
     * 查询月度价格趋势
     */
    @Aggregation(pipeline = {
        "{ $match: { 'cityName': ?0 } }",
        "{ $group: { _id: { $substr: ['$createTime', 0, 7] }, avgPrice: { $avg: '$price.unitPrice' } } }",
        "{ $sort: { _id: 1 } }",
        "{ $project: { _id: 0, month: '$_id', averagePrice: '$avgPrice' } }"
    })
    List<MonthlyPriceTrendDTO> findMonthlyPriceTrend(String city);

    /**
     * 根据区域计算平均单价
     */
    @Aggregation(pipeline = {
        "{ $match: { 'cityName': ?0 } }",
        "{ $group: { _id: '$district', avgPrice: { $avg: '$price.unitPrice' } } }",
        "{ $sort: { avgPrice: -1 } }",
        "{ $project: { _id: 0, district: '$_id', averagePrice: '$avgPrice' } }"
    })
    List<Object[]> findAverageUnitPriceByDistrict(String city);

    /**
     * 根据小区计算平均单价
     */
    @Aggregation(pipeline = {
        "{ $match: { 'cityName': ?0, 'district': ?1 } }",
        "{ $group: { _id: '$location', avgPrice: { $avg: '$price.unitPrice' } } }",
        "{ $sort: { avgPrice: -1 } }",
        "{ $project: { _id: 0, community: '$_id', averagePrice: '$avgPrice' } }"
    })
    List<Object[]> findAverageUnitPriceByCommunity(String city, String district);

    /**
     * 根据户型计算平均单价
     */
    @Aggregation(pipeline = {
        "{ $match: { 'cityName': ?0 } }",
        "{ $group: { _id: '$details.configuration', avgPrice: { $avg: '$price.unitPrice' }, count: { $sum: 1 } } }",
        "{ $sort: { count: -1 } }",
        "{ $limit: 10 }",
        "{ $project: { _id: 0, layout: '$_id', averagePrice: '$avgPrice', count: '$count' } }"
    })
    List<Object[]> findAverageUnitPriceByLayout(String city);

    /**
     * 根据城市名称统计价格相关数据
     */
    @Query(value = "{'cityName': ?0}", fields = "{'price.totalPrice': 1, 'details.areaValue': 1}")
    List<HouseInfo> findPriceStatsByCityName(String cityName);
} 